/***************************************************************************
                          Matrix.h  -  description
                             -------------------
    begin                : Wed Mar 1 2006
    copyright            : (C) 2006 by Juber
    email                : PJuber@issc_112
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
     // ###############   to implement a utility matrix class using vectors from STL

/**
  * @file Matrix.h
  * @author Juber Patel
  *
  * Utility vector and matrix classes

 */

#ifndef MATRIX_H
#define MATRIX_H

#include <iostream>
#include <vector>
//#include <algorithm>
#include <fstream>
#include <cmath>


using namespace std;


class Vector : public vector<double>
{


public:

    static const double TOLERANCE=0.0000001;

    Vector(){}
	  Vector(const Vector& another);

	/**
	  * @brief Create a new vector
	  * @param Elements number of elements in the vector
	  * @param Val initial value for all elements
	  * @return Nothing
	 */
    Vector(long elements,double val=0);
	  ~Vector();

	Vector& operator=(const Vector& another);
	bool operator<(const Vector& another);
	bool operator==(const Vector& another);
	//reference operator[](unsigned int j) const { const vector<double> * p=this; return p->operator[](j-1);  }

	static bool nearlyEqual(double num1,double num2);
	bool nearlyEqualTo(const Vector& another);
	void disp();
};



class Matrix : public vector<Vector>
{


public:


	enum DIR{RM=1,CM};


    Matrix(){}
	Matrix(const Matrix& source);
    Matrix(long rows,long coloumns,double val=0);
	Matrix(const char * fileName);    //string argument does not work
	Matrix(const Vector& v,Matrix::DIR dir=Matrix::RM);
	~Matrix();


	bool Matrix::nearlyEqualTo(const Matrix& another);

	Matrix& operator=(const Matrix& another);

	bool operator==(const Matrix& another);
	//reference operator[](unsigned int i) const { const vector<Vector> * p=this; return p->operator[](i-1); }

	bool save(const char * fileName);

	//number of rows
	long numRows() const {return this->size();}

	//number of rows

	// number of coloumns
	long numCols() const {return (*this)[0].size();}

	//use [][] to access element at given position (starts with (1,1))


	//read matrix from file

	//write matrix to file

	//display a row
	void dispRow(long rownum);

	//display the entire matrix
	void disp();

	//add 2 matrices
	Matrix operator+(const Matrix& b);

	//substract matrices
	Matrix operator-(const Matrix& b);

	//transepose of a matrix
	Matrix transepose();

	//multiply 2 matrices
	Matrix operator* (const Matrix& b);

	//multily a row by a scalar
	Matrix& multRow(long rowNumber,double scalar);

	//swap rows
	Matrix& swapRows(long first,long second);

	//add a scalar multiple of a row to another row
	Matrix& addMult(long first,double multiple,long second);

	// is the matrix symmetric
	bool isSymmetric();

	//concatenate two matrices having equal rows
	Matrix concat(const Matrix& b);

	bool nearlyEqual(double num1,double num2);
	bool hasGoodPivotIn(long rowNumber);
	bool changePivotIn(long rowNumber);

	//isuppertri
	//islowertri

};



class SquareMatrix : public Matrix
{

public:
    SquareMatrix(const char * fileName):Matrix(fileName){}


    bool isDiagonallyDominant();
    bool isSingular(){}
  	bool isInvertible(){}
	  SquareMatrix & inverse(){}
    double determinant(){}



};

#endif      //end of MATRIX_H

